package com.hundsun.fcp.webplugin;

import java.io.ByteArrayInputStream;

import android.content.Context;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.hundsun.fcp.common.FcpConfig;
import com.hundsun.fcp.common.Redirect;
import com.hundsun.fcp.common.logger.AndroidLogger;
import com.hundsun.fcp.common.logger.Logger;
import com.hundsun.fcp.common.utils.ToastUtil;
import com.hundsun.fcp.webplugin.bean.UpdateManifestBean;
import com.hundsun.fcp.webplugin.bean.VersionManifestBean;
import com.hundsun.fcp.webplugin.exception.SDCardException;
import com.hundsun.fcp.webplugin.service.IFcpDataServiceHandler;
import com.hundsun.fcp.webplugin.service.update.FcpDownloadBinaryDataService;
import com.hundsun.fcp.webplugin.service.update.FcpUpdateManifestDataService;
import com.hundsun.fcp.webplugin.service.update.IFcpDownloadBinaryDataServiceHandler;
import com.hundsun.fcp.webplugin.service.update.IUpdateListener;
import com.hundsun.fcp.webplugin.util.AssetsUtil;
import com.hundsun.fcp.webplugin.util.ZipUtil;

public class WebPluginVerification {
	private static final Logger LOGGER = AndroidLogger.getLogger() ;
	private Context mContext;
	private static WebPluginVerification instance;
	private static final String VERSION_MANIFEST_FILE_NAME = "version.android.manifest";
	private FcpDownloadBinaryDataService mDownloadingDataService;
	
	private FcpUpdateManifestDataService mUpdateManifestDataService ;
	
	private ICheckUpdateListener pCheckUpdateListener ;

	private WebPluginVerification(Context pContext) {
		mContext = pContext;
		initCheckUpdateDataService() ;
	}

	public static WebPluginVerification getInstance(Context pContext) {
		if (instance == null) {
			instance = new WebPluginVerification(pContext);
		}
		return instance;
	}
	
	private void initCheckUpdateDataService() {
		mUpdateManifestDataService = FcpUpdateManifestDataService.create(mContext) ;
		mUpdateManifestDataService.setDataServiceCallback(new IFcpDataServiceHandler() {
			
			@Override
			public void onGetError(int errorCode, String errorMsg,
					Throwable errorpThrowable) {
				 HandleError("网络连接连接错误", errorpThrowable);
			}
			
			@Override
			public void onGetData(Object responseBody) {
				UpdateManifestBean manifestBean = (UpdateManifestBean) responseBody ;
				VersionManifestBean _LocalManifestBean = getSdCardVersionManifestData(WebPluginConfig.getWebPluginDir()) ;
				if(_LocalManifestBean!=null&&_LocalManifestBean.buildNo>=manifestBean.buildNo){
					
					
					if(pCheckUpdateListener!=null){
						pCheckUpdateListener.onCheckDone();
					}
					return ;
				} 
				
				if(pCheckUpdateListener!=null){
					pCheckUpdateListener.onCheckNeedUpdate(manifestBean) ;
				}
				
			}
		}) ;
	}
	
	 
	
	public void checkPluginNeedUpdate(){
		mUpdateManifestDataService.cancel() ;
		mUpdateManifestDataService.get(null) ;
	}
	
	 public void cancelDownloading()
	 {
	    if (this.mDownloadingDataService != null) {
	      this.mDownloadingDataService.cancel();
	    }
	 }
	  
	/**
	 * 下载插件
	 * @param pIUpdateListener
	 */
	public void executeUpdate(String updateUrl,final IUpdateListener pIUpdateListener) {
		mDownloadingDataService = FcpDownloadBinaryDataService.create(mContext) ;
		mDownloadingDataService.setDataServiceCallback(new IFcpDownloadBinaryDataServiceHandler() {
			
			@Override
			public void onGetError(int errorCode, String errorMsg,
					Throwable errorpThrowable) {
				LOGGER.debug(String.format("Download android_bundle.zip fail %s=>%s", errorCode,errorMsg)) ;
				pIUpdateListener.onUpdateFailed("文件下载出错，请稍候重试", errorpThrowable) ;
			}
			
			@Override
			public void onGetData(Object responseBody) {
				try {
					if (!WebPluginConfig.existBaseDir()) {
					    throw new SDCardException("SD卡数据读取异常，请检查设置");
					 }
				} catch (Exception e) {
					pIUpdateListener.onUpdateFailed(analysisException(e), e) ;
				}
				
				try {	
					ByteArrayInputStream _ArrayInputStream = new ByteArrayInputStream((byte[])responseBody);
					String _webPluginDir = WebPluginConfig.getWebPluginDir() ;
					LOGGER.debug("Download android_bundle.zip successed, unzip to:" + _webPluginDir) ;
					ZipUtil.unZip(_ArrayInputStream, _webPluginDir);
					LOGGER.debug("android_bundle.zip unzip successed .") ;
				} catch (Exception e) {
					pIUpdateListener.onUpdateFailed("SD卡数据写入异常，请检查设置", e) ;
				}
			}
			
			@Override
			public void onStart() {
				if(pIUpdateListener!=null){
					pIUpdateListener.onUpdateStart() ;
				}
			}
			
			@Override
			public void onProgress(int bytesWritten, int totalSize) {
				if(pIUpdateListener!=null){
					pIUpdateListener.onUpdateProgress(bytesWritten, totalSize) ;
				}
			}
			
			@Override
			public void onFinish() {
				if(pIUpdateListener!=null){
					pIUpdateListener.onUpdateFinish() ;
				}
			}
		}) ;
		this.mDownloadingDataService.setDownloadUrl(updateUrl);
	    AssetsUtil.clearWebPluginAsset() ;
	    this.mDownloadingDataService.get(null);
	}
	
	private String analysisException(Throwable pThrowable){
		String error = "服务器通迅异常，请稍候重试";
		if(pThrowable instanceof SDCardException){
			error = pThrowable.getMessage() ;
		}
		
		return error ;
	}
	
	/**
	 * 读取sd上的插件版本号
	 * @param pDirPath
	 * @return
	 */
	private VersionManifestBean getSdCardVersionManifestData(String pDirPath){
		String manifestStr = AssetsUtil.readWebPluginManifest(pDirPath+VERSION_MANIFEST_FILE_NAME) ;
		if(!TextUtils.isEmpty(manifestStr)){
			return JSON.parseObject(manifestStr, VersionManifestBean.class) ;
		}
		
		return null ;
	}
	
	/**
	 * 读取assets上的插件版本号
	 * @param pDirPath
	 * @return
	 */
	private VersionManifestBean getAssetsVersionManifestData(){
		String manifestStr = AssetsUtil.readAssetsFile(mContext,VERSION_MANIFEST_FILE_NAME) ;
		LOGGER.debug("getAssetsVersionManifestData = "+manifestStr) ;
		if(!TextUtils.isEmpty(manifestStr)){
			return JSON.parseObject(manifestStr, VersionManifestBean.class) ;
		}
		
		return null ;
	}
	
	/**
	 * 比对sdcard上的与assets上的manifest文件，并把最新的zip解压到sd卡
	 */
	public void compareAssetsAndSdCardVersion(){
		try {
			VersionManifestBean _SdCardManifestBean = getSdCardVersionManifestData(WebPluginConfig.getWebPluginDir()) ;
			if(_SdCardManifestBean==null){
				AssetsUtil.copyAssetsToSDCard(mContext) ;
			}else{
				VersionManifestBean _AssetsManifestBean = getAssetsVersionManifestData() ;
				if(_AssetsManifestBean==null){
					LOGGER.debug("_AssetsManifestBean = null") ;
					return ;
				}
				if(_SdCardManifestBean.buildNo<_AssetsManifestBean.buildNo){
					AssetsUtil.copyAssetsToSDCard(mContext) ;
				}
			}
			LOGGER.debug("插件加载成功") ;
			
		} catch (Exception e) {
			e.printStackTrace();
			Redirect.makeToast(mContext, "插件加载失败") ;
		}
	}
	
	
	public ICheckUpdateListener getCheckUpdateListener() {
		return pCheckUpdateListener;
	}

	public void setCheckUpdateListener(ICheckUpdateListener pCheckUpdateListener) {
		this.pCheckUpdateListener = pCheckUpdateListener;
	}
	
	protected void HandleError(String errorMsg,
			Throwable errorThrowable) {
		try {
			if (pCheckUpdateListener != null) {
				pCheckUpdateListener.onCheckFailed(errorMsg, errorThrowable);
			}
		} catch (Exception e) {
			LOGGER.debug("HandleError", e);
		}
	}

	public static abstract interface ICheckUpdateListener
	  {
	    public abstract void onCheckDone();
	    
	    public abstract void onCheckFailed(String errorMsg, Throwable errorThrowable);
	    
	    public abstract void onCheckNeedUpdate(UpdateManifestBean pUpdateManifestBean);
	  }
}
